#include <stdio.h>
#include <stdlib.h> //free
#include <string.h> //strdup
#include <curl/curl.h> //libcurl
#include "cJSON.h"
#include "stt.h"
#include "auth.h"

char* robot_make_request(const char* apikey, const char* text)
{
    //判断输入的字符串长度不为0
    if (strlen(text) == 0)
    {
        return NULL;
    }

    cJSON* request = cJSON_CreateObject();

    cJSON* perception = cJSON_CreateObject();
    cJSON* inputText = cJSON_CreateObject();

    cJSON_AddStringToObject(inputText, "text", text);
    cJSON_AddItemToObject(perception, "inputText", inputText);
    cJSON_AddItemToObject(request, "perception", perception);

    cJSON* userInfo = cJSON_CreateObject();
    cJSON_AddStringToObject(userInfo, "apiKey", apikey);
    cJSON_AddStringToObject(userInfo, "userId", "libotao");
    cJSON_AddItemToObject(request, "userInfo", userInfo);

    //将JSON数据结构转为字符串
    return cJSON_Print(request);
}

char* robot_send_request(const char* request)
{
    FILE* fp;

    //响应消息的地址
    char* response = NULL;
    //响应消息的长度
    size_t resplen = 0;
    //创建内存文件，当通过文件句柄写入数据时，会自动分配内存
    fp = open_memstream(&response, &resplen);
    if (fp == NULL) //打开文件失败，打印错误信息并退出
    {
        perror("open_memstream() failed");
        return NULL;
    }

    //初始化HTTP客户端
    CURL* curl = curl_easy_init();


    //准备HTTP请求消息，设置API地址（URI）
    curl_easy_setopt(curl, CURLOPT_URL, "http://openapi.tuling123.com/openapi/api/v2");
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    //配置需要通过POST请求消息发送给服务器的数据
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    //发送HTTP请求消息，等待服务器的响应消息
    CURLcode error = curl_easy_perform(curl);
    if (error != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(error));
        curl_easy_cleanup(curl);
        fclose(fp);
    }
    fclose(fp);
    //释放HTTP客户端申请的资源
    curl_easy_cleanup(curl);
    // puts( response);//打印回应
    //解析回应


    cJSON* json = cJSON_Parse(response);
    if (json == NULL)
    {
        const char* error_pos = cJSON_GetErrorPtr();
        if (error_pos != NULL)
        {
            fprintf(stderr, "Error before: %s\n", error_pos);
        }
        free(response);
        return NULL;
    }

    cJSON* results = cJSON_GetObjectItem(json, "results");
    cJSON* json_list = results->child;
    cJSON* values = cJSON_GetObjectItemCaseSensitive(json_list, "values");
    cJSON* text = cJSON_GetObjectItemCaseSensitive(values, "text");
    char* line = strdup(text->valuestring);
    printf("%s\n", text->valuestring);
    //释放cjson数据结构占用的内存
    cJSON_Delete(json);
    free(response);
    return line;
    //return NULL;

}

void text2speech(const char* token, const char* text)
{
    CURL* curl = curl_easy_init();

    //发送到百度云的字符串需要进行2次URL编码
    char* temp = curl_easy_escape(curl, text, strlen(text));
    char* data = curl_easy_escape(curl, temp, strlen(temp));
    curl_free(temp);

    //拼接POST请求发送的数据
    char* postdata;
    asprintf(&postdata, "tex=%s&lan=zh&cuid=hqyj&ctp=1&aue=6&tok=%s&per=103", data, token);
    curl_free(data);

    //启动播放软件，通过管道写入音频数据
    FILE* fp = popen("aplay -q -", "w");
    if (fp == NULL)
    {
        perror("fopen() failed");
        return;
    }

    curl_easy_setopt(curl, CURLOPT_URL, "https://tsn.baidu.com/text2audio");
    //配置客户端，使用HTTP的POST方法发送请求消息
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    //配置需要通过POST请求消息发送给服务器的数据
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    //发送HTTP请求消息，等待服务器的响应消息
    CURLcode error = curl_easy_perform(curl);
    if (error != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(error));
        curl_easy_cleanup(curl);
        free(postdata);
        pclose(fp);
        return;
    }

    //释放HTTP客户端申请的资源
    curl_easy_cleanup(curl);
    free(postdata);

    //关闭管道
    pclose(fp);
}
//图灵机器人API，一次最多可以处理128个字符
#define LINE_LEN_r 2048
//保存输入字符串的缓冲区
char* stt_line;
char* read_line;
int main()
{
    //jo太郎
    char* apikey = "79e254bd69d04b2ba680bda89580fdb2";
    char* token = get_token("YjizGbsnmpOFOSTgiFckyd0v", "pNE6CYGEl7O3pGKTFGckyNOBygpYNmL6");
    //从标准输入读取一行字符
    stt_line = stt_result();
    //while (stt_line != NULL)
    //{
        //构造请求报文
        char* request = robot_make_request(apikey, stt_line);
        //if (request == NULL)
       // {
           // continue;
       // }
        //将请求报文发送给图灵机器人
        read_line = robot_send_request(request);

        text2speech(token, read_line);
    //}

    return 0;
}